package chatroom;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * 服务端
 */
public class Server {
    private ServerSocket serverSocket;//服务端套接字
    private Map<String, PrintWriter> map =new HashMap<String, PrintWriter>();//map接受昵称和IO流


    //调用构造器的同时启动服务器
    public Server(){
        try {
            System.out.println("服务器正在连接...");
            serverSocket =new ServerSocket(9999);
            System.out.println("服务端连接成功！！！");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void start(){

        while (true) {
            Socket socket=null;
            try {
                System.out.println("等待客户端连接...");
                socket = serverSocket.accept();
                System.out.println("一个客户端连接了...");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }



            //写一个conduct内部类实现runnable接口，启动一个线程，处理接收到的socket,防止被accept阻塞
            Conduct conduct=new Conduct(socket);
            Thread thread=new Thread(conduct);
            thread.start();

        }

    }

    private class Conduct implements Runnable{
        private Socket socket;

        Conduct(){}
        //有参构造函数，获取socket
        public Conduct(Socket socket){
            this.socket=socket;
        }


        @Override
        public void run() {
            PrintWriter pw=null;
            BufferedReader br= null;
            String name = null;
            try {
                OutputStream  outputStream = socket.getOutputStream();
                //转换流
                OutputStreamWriter osw = new OutputStreamWriter(outputStream,StandardCharsets.UTF_8);
                //缓冲流
                BufferedWriter bufferedWriter = new BufferedWriter(osw);
                //开启自动刷新，换行
                pw=new PrintWriter(bufferedWriter,true);


                InputStream inputStream = socket.getInputStream();
                //转换流
                InputStreamReader inputStream1 = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
                //缓冲流
                br = new BufferedReader(inputStream1);

                //第一次读取到的内容为昵称
                name = br.readLine();
                map.put(name,pw);
                System.out.println(name+"上线了,当前人数"+map.size());

                //读取流

                //判断是私聊还是群聊
                String message;
                while (true) {
                    if ((message=br.readLine())!=null){
                        //是私聊，private_chat
                        if (message.startsWith("@")){
                            private_chat(message,name);
                        }else {
                            //是群聊group_chat
                            group_chat(name+":"+message);
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //私聊方法
    public  void  private_chat(String message,String name){

        //@xxx:你好！
        String regex="@.+:.+";
        if (message.matches(regex)){
            //获取名字
           String youname = message.substring(1,message.indexOf(":"));
            if (map.containsKey(youname)) {
                message = message.substring(message.indexOf(":"));
                //迭代map,找到对应的pw
                for (Map.Entry<String,PrintWriter> map : map.entrySet()){
                    if (youname.equals(map.getKey())){
                        map.getValue().println(name+"私聊你"+message);
                    }
                }
            } else {

                PrintWriter printWriter = map.get(name);
                printWriter.println("对方不在线");
            }
        }else {
            PrintWriter printWriter = map.get(name);
            printWriter.println("私聊格式不正确");
        }
    }
    //群聊方法
    public void group_chat(String message){
        //获取名字
        for (Map.Entry<String,PrintWriter> map : map.entrySet()){
            map.getValue().println(message);
        }

    }

    public static void main(String[] args) {
        Server server=new Server();
        server.start();
    }

}
